﻿namespace Example.Configuration
{
    using System;

    public sealed class CustomSettings : IComparable
    {
        private string _setting;

        public CustomSettings()
            : this("default")
        {
        }

        public CustomSettings(string setting)
        {
            Setting = setting;
        }

        public string Setting
        {
            get
            {
                return _setting;
            }

            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                _setting = value;
            }
        }

        public static bool operator ==(CustomSettings expression1, 
                                       CustomSettings expression2)
        {
            return Compare(expression1, expression2) == 0;
        }

        public static bool operator >(CustomSettings expression1, 
                                      CustomSettings expression2)
        {
            return Compare(expression1, expression2) > 0;
        }

        public static bool operator !=(CustomSettings expression1, 
                                       CustomSettings expression2)
        {
            return Compare(expression1, expression2) != 0;
        }

        public static bool operator <(CustomSettings expression1, 
                                      CustomSettings expression2)
        {
            return Compare(expression1, expression2) < 0;
        }

        public static int Compare(CustomSettings expression1, 
                                  CustomSettings expression2)
        {
            return ReferenceEquals(expression1, expression2)
                       ? 0
                       : string.Compare(
                           ReferenceEquals(expression1, null) ? null : expression1.ToString(), 
                           ReferenceEquals(expression2, null) ? null : expression2.ToString(), 
                           StringComparison.OrdinalIgnoreCase);
        }

        public override bool Equals(object obj)
        {
            var result = false;

            if (!ReferenceEquals(obj, null))
            {
                if (ReferenceEquals(this, obj))
                {
                    result = true;
                }
                else
                {
                    var cast = obj as CustomSettings;

                    if (!ReferenceEquals(cast, null))
                    {
                        result = Compare(this, cast) == 0;
                    }
                }
            }

            return result;
        }

        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }

        public override string ToString()
        {
            return string.Concat("setting=\"", Setting, "\"");
        }

        public int CompareTo(object obj)
        {
            var value = obj as CustomSettings;

            if (!ReferenceEquals(obj, null) &&
                (value == null))
            {
                throw new ArgumentOutOfRangeException("obj");
            }

            return Compare(this, ReferenceEquals(obj, null) ? null : value);
        }
    }
}